﻿using System;
using System.IO;
using System.Xml;
using System.Linq;
using System.Diagnostics;
using System.Xml.Linq;

public class RichTextValidator
{
    private static string[] permittedAttributes = new string[] { 
        "xml:space", "xml:lang", "xmlns", "FontSize", "FontFamily", "Foreground", "FontWeight", "FontStyle", "FontStretch", "TextDecorations", "CharacterSpacing", "Typography.AnnotationAlternates", "Typography.Capitals", "Typography.CapitalSpacing", "Typography.CaseSensitiveForms", "Typography.ContextualAlternates", 
        "Typography.ContextualLigatures", "Typography.ContextualSwashes", "Typography.DiscretionaryLigatures", "Typography.EastAsianExpertForms", "Typography.EastAsianLanguage", "Typography.EastAsianWidths", "Typography.Fraction", "Typography.HistoricalForms", "Typography.HistoricalLigatures", "Typography.Kerning", "Typography.MathematicalGreek", "Typography.NumeralAlignment", "Typography.NumeralStyle", "Typography.SlashedZero", "Typography.StandardLigatures", "Typography.StandardSwashes", 
        "Typography.StylisticAlternates", "Typography.StylisticSet1", "Typography.StylisticSet10", "Typography.StylisticSet11", "Typography.StylisticSet12", "Typography.StylisticSet13", "Typography.StylisticSet14", "Typography.StylisticSet15", "Typography.StylisticSet16", "Typography.StylisticSet17", "Typography.StylisticSet18", "Typography.StylisticSet19", "Typography.StylisticSet2", "Typography.StylisticSet20", "Typography.StylisticSet3", "Typography.StylisticSet4", 
        "Typography.StylisticSet5", "Typography.StylisticSet6", "Typography.StylisticSet7", "Typography.StylisticSet8", "Typography.StylisticSet9", "Typography.Variants", "TextOptions.TextHintingMode", "TextOptions.TextFormattingMode", "TextOptions.TextRenderingMode", "FlowDirection", "Text", "HasTrailingParagraphBreakOnPaste", "TextAlignment", "LineHeight", "LineStackingStrategy", "TargetName", 
        "NavigateUri", "MouseOverForeground", "MouseOverTextDecorations"
        };
    private static string[] permittedTextElements = new string[] { "Paragraph", "Run", "LineBreak", "Span", "Bold", "Italic", "Underline", "Hyperlink" };
    private XmlReader xmlReader = null;

    public bool IsAllowed(XElement element)
    {
        return permittedTextElements.Contains(element.Name.LocalName);
    }

    public bool IsAllowed(XAttribute attribute)
    {
        return permittedAttributes.Contains(attribute.Name.LocalName);
    }

    private bool IsAllowed(string[] allowedArray)
    {
        if (!allowedArray.Contains(this.xmlReader.Name))
        {
            Debug.WriteLine(this.xmlReader.Name);
        }

        return allowedArray.Contains(this.xmlReader.Name);
    }

    private void SetupXmlReader(string inputXAML)
    {
        XmlReaderSettings settings = new XmlReaderSettings
        {
            CheckCharacters = true,
            CloseInput = true,
            ConformanceLevel = ConformanceLevel.Document,
            XmlResolver = null
        };
        this.xmlReader = XmlReader.Create(new StringReader(inputXAML), settings);
    }

    private bool ValidateAttributes()
    {
        while (this.xmlReader.MoveToNextAttribute())
        {
            if (!this.IsAllowed(permittedAttributes))
            {
                throw new ArgumentException();
            }
            string str = this.xmlReader.Value.Trim();
            if (str.StartsWith("{") && str.EndsWith("}"))
            {
                throw new ArgumentException();
            }
        }
        return true;
    }

    private bool ValidateRootElement()
    {
        if (((this.xmlReader.NodeType != XmlNodeType.Element) || !this.xmlReader.Name.Equals("Section", StringComparison.Ordinal)) || ((this.xmlReader.Prefix != string.Empty) || (this.xmlReader.LookupNamespace(string.Empty) != ClipboardXAMLSerializer.XamlNamespace)))
        {
            throw new ArgumentException();
        }
        return this.ValidateAttributes();
    }

    public bool ValidateXAML(string inputXAML)
    {
        bool flag = false;
        try
        {
            this.SetupXmlReader(inputXAML);
            if ((this.xmlReader.MoveToContent() == XmlNodeType.Element) && this.ValidateRootElement())
            {
                while (this.xmlReader.Read())
                {
                    if (this.xmlReader.NodeType == XmlNodeType.Element)
                    {
                        if ((!this.IsAllowed(permittedTextElements) || (this.xmlReader.Prefix != string.Empty)) || (this.xmlReader.LookupNamespace(string.Empty) != ClipboardXAMLSerializer.XamlNamespace))
                        {
                            throw new ArgumentException();
                        }
                        this.ValidateAttributes();
                    }
                }
                flag = true;
            }
        }
        catch (Exception)
        {
        }
        if (this.xmlReader != null)
        {
            this.xmlReader.Close();
            this.xmlReader = null;
        }
        return flag;
    }
}

